package com.gss.web.stock;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import org.apache.log4j.Logger;
import org.json.JSONArray;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import com.gss.domain.common.SearchCriteria;
import com.gss.domain.reports.ReportsParameter;
import com.gss.domain.stock.ItemDetailsDTO;
import com.gss.domain.stock.ItemTransactionDTO;
import com.gss.domain.stock.ItemTransactionDTO.OperationType;
import com.gss.service.stock.ItemService;
import com.gss.util.common.ApplicationConstant;
import com.gss.util.common.ApplicationUtilities;

@Controller
public class ItemController
{
	Logger logger = Logger.getLogger(ItemController.class);
	@Autowired
	ItemService itemService;
	
	@RequestMapping("/welcome.htm")
	public ModelAndView welcome()
	{
		ModelAndView modelAndView = new ModelAndView("welcome");
		return modelAndView;
	}
	@RequestMapping("/addItem.htm")
	public ModelAndView addItem()
	{
		ModelAndView modelAndView = new ModelAndView("addItem");
		modelAndView.addObject("itemDetailsDTO", new ItemDetailsDTO());
		return modelAndView;
	}
	@RequestMapping("/saveItem.htm")
	public ModelAndView saveItem(@Valid ItemDetailsDTO itemDetailsDTO,BindingResult bindingResult)
	{
		logger.debug(bindingResult.getAllErrors());
		boolean isDuplicate = ApplicationUtilities.checkIfExisting(ApplicationConstant.ITEM_NAME_ID_MAP.keySet(), itemDetailsDTO.getItemName());
		if(isDuplicate)
			bindingResult.rejectValue("itemName", "itemNameExists", "Item Name Already Exists");
		if(bindingResult.hasErrors())
		{
			ModelAndView modelAndView = new ModelAndView("addItem");
			modelAndView.addObject("itemDetailsDTO", new ItemDetailsDTO());
			return modelAndView;			
		}
		ModelAndView modelAndView = new ModelAndView();
		if(itemService.saveItem(itemDetailsDTO))
		{
			modelAndView.setViewName("success");
		}
		else{
			modelAndView.setViewName("failed");
		}
		return modelAndView;
	}
	@RequestMapping("/searchItem.htm")
	public ModelAndView searchItem()
	{
		ModelAndView modelAndView = new ModelAndView("searchItem");
		return modelAndView;
	}
	@RequestMapping("/searchItemTransaction.htm")
	public ModelAndView searchItemTransaction()
	{
		ModelAndView modelAndView = new ModelAndView("searchItemforTransaction");
		modelAndView.addObject("searchCriteria", new SearchCriteria());
		return modelAndView;		
	}
	@RequestMapping("/viewTransaction.htm")
	public ModelAndView viewTransactionforItem(@ModelAttribute SearchCriteria searchCriteria) throws ParseException
	{
		ModelAndView modelAndView = new ModelAndView("viewTransaction");
		List<ItemTransactionDTO> transactionDTOs = itemService.getItemTransaction(searchCriteria);
		logger.debug(transactionDTOs);
		modelAndView.addObject("transactionDTOs", transactionDTOs);
		modelAndView.addObject("itemName", searchCriteria.getItemName());
		return modelAndView;
	}
	@RequestMapping("/editItemPage.htm")
	public ModelAndView editItemPage(@RequestParam String itemName)
	{
		logger.debug(itemName);
		ModelAndView modelAndView = new ModelAndView();
		ItemDetailsDTO detailsDTO = ApplicationConstant.ITEM_ID_ITEM_MAP.get(itemName);
		logger.debug(detailsDTO.getItemId());
		modelAndView.addObject("itemDetails",detailsDTO);
		return modelAndView;
	}
	@RequestMapping("/updateItem.htm")
	public ModelAndView updateItem(@ModelAttribute ItemDetailsDTO itemDetails,@RequestParam("oldItemName") String oldItemName)
	{		
		ModelAndView modelAndView = new ModelAndView();
		logger.debug(itemDetails.getItemId());
		logger.debug(itemDetails.getItemStock());
		if(itemService.updateItemDetails(itemDetails,oldItemName))
		{
			modelAndView.setViewName("success");
		}
		else{
			modelAndView.setViewName("failed");
		}
		return modelAndView;
	}
	@RequestMapping("/itemTransaction.htm")
	public ModelAndView itemTransaction()
	{
		ModelAndView modelAndView = new ModelAndView("itemTransaction");
		ItemTransactionDTO transactionDTO = new ItemTransactionDTO();
		transactionDTO.setOpertionType(OperationType.Purchase);
		modelAndView.addObject("itemTransactionDTO", transactionDTO);
		return modelAndView;
	}
	@InitBinder
	public void binder(WebDataBinder binder)
	{
		SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy");
		dateFormat.setLenient(false);
		binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
	}
	@RequestMapping("/saveTransaction.htm")
	public ModelAndView saveTransaction(@Valid ItemTransactionDTO itemTransactionDTO,BindingResult bindingResult)
	{
		ModelAndView modelAndView = new ModelAndView();
		if(bindingResult.hasErrors())
		{
			modelAndView.setViewName("itemTransaction");
			modelAndView.addObject("itemTransactionDTO", new ItemTransactionDTO());	
		}
		
		if(itemService.saveTransaction(itemTransactionDTO))
			modelAndView.setViewName("success");
		else
			modelAndView.setViewName("failed");
		return modelAndView;
	}
	@RequestMapping("/itemFilter.htm")
	public ModelAndView itemFilter()
	{
		ModelAndView modelAndView = new ModelAndView("ItemFilter");
		return modelAndView;
	}
	@RequestMapping("/availableStockReport.htm")
	public ModelAndView availableStockReport(@RequestParam String itemName)
	{
		ModelAndView modelAndView = new ModelAndView("availableStockReport");

		if(itemName.equals(""))
			modelAndView.addObject("itemDetails", itemService.loadAllItem());
		else
			modelAndView.addObject("itemDetails",ApplicationConstant.ITEM_ID_ITEM_MAP.get(itemName));
		return modelAndView;
	}
	@RequestMapping("/generatePurchaseorder.htm")
	public ModelAndView generatePurchaseorder()
	{
		ModelAndView modelAndView = new ModelAndView("purchaseOrder");
		List<ItemDetailsDTO> itemDetailsDTOs = itemService.getItemLessinStock();
		modelAndView.addObject("itemDetails", itemDetailsDTOs);
		modelAndView.addObject("reportParams", new ReportsParameter());
		return modelAndView;		
	}
	@RequestMapping("/getItemList.htm")
	public void getItemList(@RequestParam String term,HttpServletResponse httpServletResponse)
	{
		JSONArray jsonArray = new JSONArray();
		term = term.trim().toLowerCase();
		List<String> temp = new ArrayList<String>();
		for(String tagName : ApplicationConstant.ITEM_NAME_ID_MAP.keySet()){
			if(tagName.toLowerCase().contains(term))
				temp.add(tagName);
		}
		if(temp.size()>0){
			Collections.sort(temp);
			for(String name : temp)
				jsonArray.put(name);
		}
		try {
			httpServletResponse.getWriter().print(jsonArray.toString());
		} catch (IOException e) {
			e.printStackTrace();
		}		
	}
	@RequestMapping("/checkStock.htm")
	public void checkStock(@ModelAttribute ItemTransactionDTO itemTransactionDTO,HttpServletResponse response) throws IOException
	{
		if(ApplicationConstant.ITEM_STOCK_MAP.containsKey(itemTransactionDTO.getItemName()))
		{
			response.getWriter().write(ApplicationConstant.ITEM_STOCK_MAP.get(itemTransactionDTO.getItemName()).toString());
		}
		else
			response.getWriter().write("0");
		
	}
}
